# -*- coding: utf   -8 -*-
import kivy
from collections import defaultdict

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from ui.unclikableButton import UnButton
from hat_widget import HatWidget
from kivy.properties import NumericProperty

from model import gamestate


def len_of_failed_words(WGR_list):
    return sum(1 if word.result == 1 else 0 for word in WGR_list)


def len_of_guessed_words(WGR_list):
    return sum(1 if word.result == 0 else 0 for word in WGR_list)


def creating_result_table(gamestate):
    """
    Create 3 dict.
    1)results_for_person_guessed : player name -> guessed words count
    2)result_for_person_described : player_name -> described_words count
    3)result_for_pair: (player name, player name) -> pair's score
    4)result_for_person_guessed_and_described: player_name -> guessed and
    described words count
    Args:
        gamestate: GameState
    """
    rounds_list = gamestate.rounds
    players = gamestate.players.players
    is_pair_strategy = gamestate.players.players_select_strategy.\
        is_pair_strategy()

    result_for_pair = defaultdict(lambda: 0)
    result_for_person_guessed = defaultdict(lambda: 0)
    result_for_person_described = defaultdict(lambda: 0)
    result_for_person_guessed_and_described = defaultdict(lambda: 0)

    if (is_pair_strategy):
        pairs = gamestate.players.players_select_strategy.get_pairs()
        for pair_of_players in pairs:
            pair_names = (pair_of_players[0].name, pair_of_players[1].name)
            p1, p2 = pair_names
            result_for_person_guessed[p1] = 0
            result_for_person_described[p2] = 0
            result_for_pair[frozenset(pair_names)] = 0
            result_for_person_guessed_and_described[p1] = 0

    else:
        for player in players:
            result_for_person_guessed[player.name] = 0
            result_for_person_described[player.name] = 0
            result_for_person_guessed_and_described[player.name] = 0

    for r in rounds_list:
        if r.is_replayed:
            continue
        pair_names = (r.players_pair[0].name, r.players_pair[1].name)
        p1, p2 = pair_names
        guessed = len_of_guessed_words(r.words)
        result_for_person_guessed[p1] += guessed
        result_for_person_described[p2] += guessed
        result_for_pair[frozenset(pair_names)] += guessed
        result_for_person_guessed_and_described[p1] += guessed
        result_for_person_guessed_and_described[p2] += guessed

    return (result_for_pair, result_for_person_described,
            result_for_person_guessed, result_for_person_guessed_and_described)


class TwoPlayerTableLine(BoxLayout):
    def __init__(self, name1, guessed1, described1,
                 name2, guessed2, described2,
                 summ, **kwargs):
        self.name1 = name1
        self.guessed1 = guessed1
        self.described1 = described1
        self.name2 = name2
        self.guessed2 = guessed2
        self.described2 = described2
        self.summ = summ
        super(TwoPlayerTableLine, self).__init__(**kwargs)


class OnePlayerTableLine(BoxLayout):
        def __init__(self, name, guessed, described, summ, **kwargs):
            self.name = name
            self.guessed = guessed
            self.described = described
            self.summ = summ
            super(OnePlayerTableLine, self).__init__(**kwargs)


class ResultsGeneral(BoxLayout):
    words_remaining = NumericProperty()
    words_failed = NumericProperty()

    def __init__(self, **kwargs):
        super(ResultsGeneral, self).__init__(**kwargs)

    def init_widget(self, gamestate, presenter):
        self.presenter = presenter
        self.gamestate = gamestate
        self.gamestate.shall_change = False

        self.words_remaining = len(self.gamestate.hat.words)
        self.words_failed = sum([len_of_failed_words(game_round.words)
                                 for game_round in self.gamestate.rounds])

        if self.gamestate.rounds is None:
            self.gamestate.rounds = []
        self.sortid = 3
        self.rev = True
        self.fill_results_list()
        self.word_list.bind(minimum_height=self.word_list.setter('height'))

    def table_butt_clicked(self, butname):
        if butname == self.sortid:
            self.rev = not self.rev
        else:
            self.sortid = butname
            self.rev = True
        self.word_list.clear_widgets()
        self.fill_results_list()

    def fill_results_list(self):
        dict_of_pair_results, dict_of_guessed_players_results, \
            dict_of_described_players_results, \
            dict_of_guessed_and_described_players_results = \
            creating_result_table(self.gamestate)

        if self.gamestate.players.players_select_strategy.is_pair_strategy():
            for pair, result in sorted(dict_of_pair_results.items(),
                                       key=lambda x: x[1],
                                       reverse=self.rev):
                pair = sorted(pair)

                described1 = dict_of_described_players_results[pair[0]]
                described2 = dict_of_described_players_results[pair[1]]

                guessed1 = dict_of_guessed_players_results[pair[0]]
                guessed2 = dict_of_guessed_players_results[pair[1]]

                self.word_list.add_widget(TwoPlayerTableLine(pair[0],
                                                             str(guessed1),
                                                             str(described1),
                                                             pair[1],
                                                             str(guessed2),
                                                             str(described2),
                                                             str(result)))
        else:
            for player, result in \
                sorted(dict_of_guessed_and_described_players_results.items(),
                       key=lambda x: x[1],
                       reverse=self.rev):

                described = dict_of_described_players_results[player]
                guessed = dict_of_guessed_players_results[player]

                self.word_list.add_widget(OnePlayerTableLine(player,
                                                             str(guessed),
                                                             str(described),
                                                             str(guessed +
                                                                 described)))
